package com.alks.function.service.impl.stockdept.pcfactorystockquery;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.beanutils.CollUtils;
import com.alks.common.utils.beanutils.StringUtils;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.ReportStockDTO;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.ReportStockInDTO;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.ReportStockOutDTO;
import com.alks.function.data.request.stockdept.pcfactorystockwork.ReportInStockQueryRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.ReportStockInQueryRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.ReportStockOutQueryRequest;
import com.alks.function.data.vo.stock.*;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcFinishCollectDetailMapper;
import com.alks.function.service.stockdept.pcfactorystockquery.IStockWorkReportService;
import com.github.pagehelper.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author: chen
 * @date: 2024/11/14
 * @description: 仓储作业报表Service
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class StockWorkReportServiceImpl implements IStockWorkReportService {

    private final PcFinishCollectDetailMapper finishCollectDetailMapper;

    @Override
    @AutoPageAop
    public PageDataVO<ReportStockInVO> reportStockIn(ReportStockInQueryRequest request) {
        PageDataVO<ReportStockInVO> resVO = new PageDataVO<>();
        List<ReportStockInVO> res = new ArrayList<>();
        // 明细数据
        List<ReportStockInDTO> list= finishCollectDetailMapper.reportStockIn(request);
        Page<ReportStockInDTO> page = (Page<ReportStockInDTO>) list;
        resVO.setTotal(page.getTotal());
        if (!CollUtils.isEmpty(list)) {
            // 数据库查询每个线别的累计数据
            List<ReportStockInDTO> sumList= finishCollectDetailMapper.reportStockInSum(request);
            Map<String, ReportStockInDTO> sumMap = sumList.stream()
                    .collect(Collectors.toMap(ReportStockInDTO::getDeptNo, e -> e));
            // 分组汇总
            Map<String, List<ReportStockInDTO>> map = list.stream().collect(
                    Collectors.groupingBy(ReportStockInDTO::getDeptNo)
            );
            map.keySet().forEach(key -> {
                // 排序
                List<ReportStockInDTO> dtos = map.get(key).stream()
                        .sorted(Comparator.comparing(ReportStockInDTO::getLotNo))
                        .collect(Collectors.toList());
                // 数据转化
                List<ReportStockInVO.OrderVO> details = dtos.stream()
                        .map(e->{
                            ReportStockInVO.OrderVO orderVO = new ReportStockInVO.OrderVO();
                            BeanUtil.copyProperties(e, orderVO);
                            orderVO.setInOweQty(orderVO.getOrderQty() - (orderVO.getPairInQty() != null ? orderVO.getPairInQty() : 0));
                            return orderVO;
                        })
                        .collect(Collectors.toList());
                res.add(new ReportStockInVO(map.get(key).get(0).getLine(), details));
                res.add(new ReportStockInVO("合计",
                        Collections.singletonList(new ReportStockInVO.OrderVO(sumMap.get(key).getQty()))));
            });
            ReportStockInVO countVo = new ReportStockInVO("总合计",
                    Collections.singletonList(new ReportStockInVO.OrderVO(sumList.stream().mapToInt(ReportStockInDTO::getQty).sum())));
            res.add(countVo);

            resVO.setRows(res);
        }
        return resVO;
    }

    @Override
    @AutoPageAop
    public PageDataVO<ReportStockOutVO> reportStockOut(ReportStockOutQueryRequest request) {
        PageDataVO<ReportStockOutVO> resVO = new PageDataVO<>();
        List<ReportStockOutVO> res = new ArrayList<>();
        // 明细数据
        List<ReportStockOutDTO> list= finishCollectDetailMapper.reportStockOut(request);
        Page<ReportStockOutDTO> page = (Page<ReportStockOutDTO>) list;
        resVO.setTotal(page.getTotal());
        if (!CollUtils.isEmpty(list)) {
            // 数据库查询每个线别的累计数据
            List<ReportStockOutDTO> sumList= finishCollectDetailMapper.reportStockOutSum(request);
            Map<String, ReportStockOutDTO> sumMap = sumList.stream()
                    .collect(Collectors.toMap(ReportStockOutDTO::getCustom, e -> e));
            // 分组汇总
            Map<String, List<ReportStockOutDTO>> map = list.stream().collect(
                    Collectors.groupingBy(ReportStockOutDTO::getCustom)
            );
            map.keySet().forEach(key -> {
                // 排序
                List<ReportStockOutDTO> dtos = map.get(key).stream()
                        .sorted(Comparator.comparing(ReportStockOutDTO::getLotNo))
                        .collect(Collectors.toList());
                // 数据转化
                List<ReportStockOutVO.OrderVO> details = dtos.stream()
                        .map(e->{
                            ReportStockOutVO.OrderVO orderVO = new ReportStockOutVO.OrderVO();
                            BeanUtil.copyProperties(e, orderVO);
                            orderVO.setOutOweQty(orderVO.getOrderQty() - (orderVO.getPairOutQty() != null ? orderVO.getPairOutQty() : 0));
                            return orderVO;
                        })
                        .collect(Collectors.toList());
                res.add(new ReportStockOutVO(map.get(key).get(0).getCustom(), details));
                res.add(new ReportStockOutVO("合计",
                        Collections.singletonList(new ReportStockOutVO.OrderVO(sumMap.get(key).getQty()))));
            });
            ReportStockOutVO countVo = new ReportStockOutVO("总合计",
                    Collections.singletonList(new ReportStockOutVO.OrderVO(sumList.stream().mapToInt(ReportStockOutDTO::getQty).sum())));
            res.add(countVo);

            resVO.setRows(res);
        }
        return resVO;
    }

    @Override
    @AutoPageAop
    public PageDataVO<ReportStockVO> reportInStock(ReportInStockQueryRequest request) {
        PageDataVO<ReportStockVO> resVO = new PageDataVO<>();
        List<ReportStockVO> res = new ArrayList<>();
        if (!StringUtils.isEmpty(request.getOrderParam())) {
            if (!Arrays.asList(ReportInStockQueryRequest.ORDER_FIELDS).contains(request.getOrderParam())) {
                throw new ServiceErrorException("排序参数非法，请核查！！！");
            } else {
                request.setOrderParam(StringUtils.convertToUpper(request.getOrderParam()));
            }
        }
        // 明细数据
        List<ReportStockDTO> list= finishCollectDetailMapper.reportStock(request);
        Page<ReportStockDTO> page = (Page<ReportStockDTO>) list;
        resVO.setTotal(page.getTotal());
        if (!CollUtils.isEmpty(list)) {
            list.forEach(e -> {
                ReportStockVO vo = new ReportStockVO();
                BeanUtil.copyProperties(e, vo);
                vo.setInOweQty(vo.getOrderQty() - (vo.getInQty() != null ? vo.getInQty() : 0));
                vo.setOutOweQty(vo.getOrderQty() - (vo.getOutQty() != null ? vo.getOutQty() : 0));
                res.add(vo);
            });
            resVO.setRows(res);
        }
        return resVO;
    }

    @Override
    public InvoicesStockVO invoiceStock(String dateStr, String collectType) {
        LocalDate date = LocalDateTimeUtil.parseDate(dateStr);
        InvoicesStockVO invoicesStockVO = new InvoicesStockVO();
        invoicesStockVO.setYear(String.valueOf(date.getYear()));
        invoicesStockVO.setMonth(String.format("%02d", date.getMonthValue()));
        invoicesStockVO.setDay(String.format("%02d", date.getDayOfMonth()));

        LocalDateTime startTime = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
        List<InvoicesStockDetailVO> detailList = finishCollectDetailMapper.invoiceStock(startTime, endTime, collectType);
        AtomicInteger tagIndex = new AtomicInteger();
        detailList.forEach(e -> e.setTag(tagIndex.incrementAndGet()));
        invoicesStockVO.setDetailList(detailList);
        invoicesStockVO.setTotalOrderQty(detailList.stream().mapToInt(InvoicesStockDetailVO::getOrderQty).sum());
        invoicesStockVO.setTotalQty(detailList.stream().mapToInt(InvoicesStockDetailVO::getQty).sum());
        invoicesStockVO.setStockNo(String.format("RVTH%s%03d",  date.format(DateTimeFormatter.ofPattern("yy")), date.getDayOfYear()));
        return invoicesStockVO;
    }
}
